/**
 * Project: TacticaPescaditos
 * File: SupportSpotCalculator.java
 */
package org.javahispano.javacup.tacticas_aceptadas.Pescaditos.com.chidotronics.javacup;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.javahispano.javacup.modelo.Constantes;

import org.javahispano.javacup.tacticas_aceptadas.Pescaditos.com.chidotronics.javacup.geometrics.Vector2D;

/**
 * @author Carlos Alberto
 * class: SupportSpotCalculator
 */
public class SupportSpotCalculator  {

	private static final double PASS_SAFE_SCORE = 3;
	private static final double POSSIBLE_GOAL_SCORE = 5;
	private static final double FROM_CONTROLLING_PLAYER_SCORE = 1;

	/**
	 * @param tactica
	 */
	SupportSpotCalculator(TacticaPescaditos tactica) {
		this.owner = tactica;
		this.random = new Random(20);
		initializeSpots();
		
		
	}

	private void initializeSpots() {
		int rows = 6;
		int columns = 6;
		double width = Constantes.ANCHO_CAMPO_JUEGO * 0.75;
		double height =  Constantes.LARGO_CAMPO_JUEGO*0.35 ;
		
		
		spots = new ArrayList<SupportSpot>(rows*columns);
		double offsetX = width / columns;
		double offsetY =  height/rows;
		double startX = (offsetX - width)/2;
		double startY = 50 ;
		
		for (int j = rows-1; j >= 0; j--) {
			double posY = startY - j*offsetY;
			for (int i = columns-1; i >= 0; i--) {
				if (j==0 && (i < 2 || i > 3)){
					continue;
				}
				double posX = startX + i*offsetX;
				SupportSpot spot = new SupportSpot(new Vector2D(posX,posY),1);
				spots.add(spot);
			}
			
		}
		
	}

	class SupportSpot{    
		/**
		 * @param pos
		 * @param score
		 */
		SupportSpot(Vector2D pos, double score) {
			position = pos;
			this.score = score;			
		}
		Vector2D  position;
		double    score;
		
		
	}
	
	private TacticaPescaditos owner;

	
	private SupportSpot bestSupportingSpot;
	
	private List<SupportSpot> spots;
	
	private int counter;
	
	private Random random;
	


	public Vector2D getBestSupportingSpot() {
		  if (bestSupportingSpot == null  ) {
			  return determineBestSupportingPosition();
		  }
		  
		  
		  

		return bestSupportingSpot.position;
	}

	public Vector2D determineBestSupportingPosition() {

		if (counter < 0  && bestSupportingSpot != null){
			counter = 2 + random.nextInt(3);
			return bestSupportingSpot.position;
		}

		bestSupportingSpot = null;

		Player<?> controllingPlayer = owner.getControllingPlayer();




		counter--;

		bestSupportingSpot = null;



		double bestScoreSoFar = 0.0;


		double maxPassRangeSq = controllingPlayer.getMaxPassRangeSq();
		double optimalDistance = 10;
		Vector2D ballTarget = new Vector2D(0, Constantes.centroArcoSup.getY());	
		for (SupportSpot curSpot : spots)
		{

			double distSq = controllingPlayer.getPosition().distanceSq(curSpot.position);


			curSpot.score = 1.0;

	

				double distanceSqToGoal = ballTarget.distanceSq(curSpot.position);
				double dist = Math.sqrt(distSq);
				double power = controllingPlayer.getKickForce()*0.8;

				if (  owner.isPassSafeFromAllOpponents( controllingPlayer.getPosition(),
						curSpot.position,
						null,power,TacticaPescaditos.PASS_ANGLE
				))   {
					curSpot.score += PASS_SAFE_SCORE;
				}

				if (owner.getSupportingPlayer()!=null) {
					dist = owner.getControllingPlayer().getPosition()
					.distance(curSpot.position);			
					double temp = Math.abs(optimalDistance - dist);

					if (temp < optimalDistance) {


						curSpot.score += FROM_CONTROLLING_PLAYER_SCORE *
						(optimalDistance-temp)/optimalDistance;  
					}

				}


				if(distanceSqToGoal < maxPassRangeSq )  {
					curSpot.score += POSSIBLE_GOAL_SCORE;
				}   
			


			if (curSpot.score > bestScoreSoFar) {
				bestScoreSoFar = curSpot.score;

				bestSupportingSpot = curSpot;
			}    

		}

		return bestSupportingSpot.position;
	}


	public List<Vector2D> getSpots() {
		List<Vector2D> l = new ArrayList<Vector2D>(spots.size());
		for (SupportSpot spot:spots){
			l.add(spot.position);
		}
		
		return l;
	}

}
